package com.shp.utils;

import org.apache.logging.log4j.util.PropertiesUtil;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;

/**
 * Description:
 * ip工具类
 * @author zwl
 * @version 1.0
 * @date 2020/3/19 3:51
 */
public class IpUtil {
    /**
     * 标志位
     */
    private static String flag;
    /**
     * ip集合
     */
    private static Properties ipProps = new Properties();

    private static String ipBlackPath;

    static{
        try {
            ipProps.load(PropertiesUtil.class.getResourceAsStream("/upload.properties"));
            ipBlackPath = ipProps.getProperty("ip-black-path");
            ipProps = new Properties();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取主机ip
     * @param request HttpServletRequest
     * @return ip
     */
    public static String getIp(HttpServletRequest request) {
        // 获取用户的ip
        String ip = request.getHeader("X-Forwarded-For");
        // 如果用户未使用代理，直接获取主机ip；若使用了代理，绕过防火墙获取客户真实ip
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
                if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                        ip = inet.getHostAddress();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                }
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (String s : ips) {
                if (!("unknown".equalsIgnoreCase(s))) {
                    ip = s;
                    break;
                }
            }
        }
        return ip;
    }

    /**
     * 校验ip是否加入黑名单
     * @param ip 客户端的ip地址
     * @return true 代表是在黑名单；false 不是
     */
    public static boolean checkIpBreak(String ip) throws IOException {
        if (ip != null) {
            String str = UuidUtil.getUuid();
            if(!str.equals(flag)){
                // 重新加载ip
                loadIp();
            }
            Enumeration<?> en = ipProps.propertyNames();
            String key;
            while (en.hasMoreElements()) {
                key = (String) en.nextElement();
                if (ip.equals(key)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 载入ip,ip-black.properties置于类路径下
     */
    public static void loadIp() throws IOException {
        ipProps.clear();
        InputStream in = new FileInputStream(ipBlackPath);
        ipProps.load(in);
        // 关闭资源
        in.close();
    }

    /**
     * 将所有黑名单ip，读取到List中
     * @return  List<String>
     * @throws IOException 黑名单ip读取出错
     */
    public static List<String> getIpBlackList() throws IOException {
        loadIp();
        List<String> ipList = new ArrayList<String>();
        Enumeration<?> en = ipProps.propertyNames();
        while (en.hasMoreElements()){
            ipList.add((String)en.nextElement());
        }
        return ipList;
    }

    /**
     * 将ip写入ip-black.properties文件
     * @param ip ip地址
     */
    public static void writeIp(String ip) throws IOException {
        loadIp();
        OutputStream fos = new FileOutputStream(ipBlackPath);
        ipProps.setProperty(ip, "ip-black");
        ipProps.store(fos, "update " + ip);
        fos.close();
    }

    /**
     * 移除ip
     * @param ip
     */
    public static void deleteElem(String ip) throws IOException {
        loadIp();
        OutputStream fos = new FileOutputStream(ipBlackPath);
        ipProps.remove(ip);
        ipProps.store(fos, "del " + ip);
        fos.close();
    }
}
